import { ICompleteCloudbaseContext, IContextParam } from '@cloudbase/node-sdk';

// Scf for Serverless Cloud Function
// Req for Request

export type ScfReqHeaders = {
  host: string,
  accept: string,
  connection: string,
  'accept-encoding': string,
  'accept-language': string,
  'user-agent': string,
  'x-client-proto': string,
  'x-client-proto-ver': string,
  'x-forwarded-for': string,
  'x-forwarded-proto': string,
  'x-nws-log-uuid': string,
  'x-origin-host': string,
  'x-real-ip': string,
  'x-stgw-time': string,
  'x-tencent-ua': string,
} & {
  [k: string]: unknown
}

export type ScfReqMultiValueHeaders<T extends ScfReqHeaders = ScfReqHeaders> = {
  [Property in keyof T]: T[Property][];
}

export type ScfReqContext = {
  appId: string,
  envId: string,
  requestId: string,
  uin: string,
}

/**
 * 当 SCF 作为一个 Request 时的 Event
 */
export type ScfReqEvent = {
  headers: ScfReqHeaders,
  multiValueHeaders: ScfReqMultiValueHeaders,
  httpMethod: string,
  body?: string,
  isBase64Encoded: boolean,
  path: string,
  queryStringParameters: Record<string, unknown>,
  requestContext: ScfReqContext,
};

/**
 * 当 SCF 作为一个 callFunction 时的 Event
 */
export type ScfCallEvent<T extends Record<string, unknown>> = T;

/**
 * 一般一个云函数最好从命名上就进行区分，比如：
 *
 * - api-cf-name -> 针对 path 挂载，
 * - fn-cf-name -> 针对云函数，以 app.callFunction
 *
 * 那么：
 *
 * - 在 api-cf-name 中，应该明确使用 ScfReqEvent
 * - 在 fn-cf-name 中，应该明确使用 ScfCallEvent<CustomType>
 */
export type ScfEvent<CallEvent extends Record<string, unknown>> = ScfReqEvent | CallEvent;

/**
 * ScfParamContext 指 Scf 传入的 Context，参考以下代码
 *
 * ```typescript
 * exports.main = async ({ mail }: ScfCallEvent<{ mail?: SendMailOptions }>, context: ScfParamContext) => {
 * }
 * ```
 */
export interface ScfParamContext extends IContextParam {
  callbackWaitsForEmptyEventLoop: boolean,
  tencentcloud_region: string,
  tencentcloud_appid: string,
  tencentcloud_uin: string,
}

/**
 * 针对的是 `getCloudbaseContext(): ICompleteCloudbaseContext` 返回类型的拓展类型
 *
 * `getCloudbaseContext` 这个返回的是明确的 `{ ...Context, ...envVariables }`，可以参考以下示例：
 *
 * ```json5
 * {
 *   "TENCENTCLOUD_RUNENV": "SCF",
 *   "SCF_NAMESPACE": "SCF_NAMESPACE",
 *   "TCB_CONTEXT_KEYS": "TCB_TRACELOG,TCB_ENV,TCB_SEQID,TCB_SOURCE_IP,TCB_SOURCE,TCB_CONTEXT_CNFG",
 *   "TENCENTCLOUD_SECRETID": "TENCENTCLOUD_SECRETID",
 *   "TENCENTCLOUD_SECRETKEY": "TENCENTCLOUD_SECRETKEY",
 *   "TENCENTCLOUD_SESSIONTOKEN": "TENCENTCLOUD_SESSIONTOKEN",
 *   "TRIGGER_SRC": "tcbgw",
 *   "TCB_CONTEXT_CNFG": "{\"URL\":\"http://URL/admin\"}",
 *   "TCB_TRACELOG": "TCB_TRACELOG",
 *   "TCB_ENV": "TCB_ENV",
 *   "TCB_SEQID": "TCB_SEQID",
 *   "TCB_SOURCE_IP": "TCB_SOURCE_IP",
 *   "TCB_SOURCE": "tcbgw",
 *   // 自定义环境变量 envVariables
 *   "keyA": "valueA",
 *   "test": "test1"
 * }
 * 
 * ```
 *
 * 这个类型，一般用于扩展 `getCloudbaseContext` 返回的类型，如：
 *
 * `const { envName } = getCloudbaseContext() as ScfEnvContext<CustomType>`
 */
export type ScfEnvContext<MixIn extends Record<string, unknown> = Record<string, unknown>> = ICompleteCloudbaseContext & MixIn;
